import base64
import datetime
import json
import random

import pytz

from util.influx_connect import InfluxConnect
from util.kafka_producer_connect import KafkaProducerConnect
from util.middleware import get_lock_middleware
from util.redis_connect import RedisPoolConnect
from util.response_format import ResponseFormat

# 连接对象放在函数外部，定义为全局变量，可以减少连接实例的创建销毁带来的性能浪费
# 消息队列生产者
PRODUCER = KafkaProducerConnect()
# 红包剩余金额剩余个数缓存统计
REDIS_POOL_INFO = RedisPoolConnect(0)
# influx连接
INFLUX_CONNECT = InfluxConnect()
# influx_database名
INFLUX_DATABASE = "every_topic_red_envelope_record"


@get_lock_middleware
def handler(event, context):
    """
    抢红包Api
    post请求参数
    topicId 消息队列标题名，因influxdb的原因，topic_id不能带有“-”号
    redEnvelopeId 红包id
    userName 用户名
    """
    logger = context.getLogger()
    params = json.loads(base64.b64decode(event["body"]).decode().replace("'", '"'))
    logger.info(params)
    red_envelope_id = params.get("redEnvelopeId")
    topic_id = params.get("topicId")
    user_name = params.get("userName")
    # 获取剩余红包金额和个数
    value = json.loads(REDIS_POOL_INFO.find_key_value(red_envelope_id))
    total_amount = value.get("totalAmount")
    total_count = value.get("totalCount")
    # 因influxdb的原因，topic_id不能带有“-”号
    query_result = INFLUX_CONNECT.query(
        f"SELECT redEnvelopeId,userName,getMoney,localTime,time"
        f" FROM {topic_id} WHERE redEnvelopeId='{red_envelope_id}'", database=INFLUX_DATABASE)
    # 用户已抢过红包
    result = list()
    is_grab = False
    for query_value in query_result.get_points():
        if user_name == query_value.get("userName"):
            is_grab = True
        result.append(query_value)
    if is_grab:
        return ResponseFormat({"code": 200, "msg": "你已抢过红包", "redEnvelopeInfo": result}, 200).to_json()
    # 红包数量为0时
    if total_count <= 0:
        return ResponseFormat({"code": 200, "msg": "红包抢完啦", "redEnvelopeInfo": result}, 200).to_json()
    # 红包数量大于0
    rate = 1 if total_count == 1 else float("%.2f" % random.random())
    get_money = total_amount * rate
    # 记录剩下红包数量及红包金额
    REDIS_POOL_INFO.set_key_value(
        red_envelope_id, json.dumps({"totalAmount": total_amount - get_money, "totalCount": total_count - 1}))
    # 记录时间
    now_time = datetime.datetime.now()
    local_time = now_time.strftime("%Y/%m/%d %H:%M:%S")
    zero_time = now_time.astimezone(pytz.timezone("UTC")).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
    # 记录红包被抢记录
    INFLUX_CONNECT.write_points([{
        "measurement": topic_id,
        "tags": {
            "redEnvelopeId": red_envelope_id,
        },
        "fields": {
            "userName": user_name,
            "getMoney": get_money,
            "localTime": local_time,
        }}], database=INFLUX_DATABASE)
    # 通过消息队列发送广播
    msg = {"message": "{0} 抢了红包".format(user_name), "messageType": 1, "userName": None, "topicId": topic_id}
    try:
        PRODUCER.send_msg(topic_id, msg)
    except ConnectionError:
        logger.error("kafka连接错误，请检查kafka配置信息")
        return ResponseFormat({"code": 500, "msg": "服务器错误"}, 500).to_json()
    result.append({"redEnvelopeInfo": red_envelope_id, "userName": user_name, "getMoney": get_money,
                   "localTime": local_time, "time": zero_time})
    return ResponseFormat({"code": 200, "msg": "恭喜你抢到了红包", "redEnvelopeInfo": result}, 200).to_json()